package fr.vod.net;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

import android.util.Log;

public class NetworkWatcher {

	private boolean isAlreadyUnloaded = false;
	private long lastKey = 0;
	Map<Long, Long> uploadMap = new HashMap<Long, Long>();
	Map<Long, Long> downloadMap = new HashMap<Long, Long>();

	private long startTimestamp;
	private long endTimestamp;

	public int totalBytesSent;
	public int totalBytesReceived;

	public NetworkWatcher startWatching() {
		this.startTimestamp = System.currentTimeMillis();
		return this;
	}

	public void stopWatching() {
		this.endTimestamp = System.currentTimeMillis();
	}

	public void addSentBytes(int bytesSize, long currentTimestamp) {
		totalBytesSent += bytesSize;
		addUploadData(bytesSize, currentTimestamp);
	}

	public void addReceivedBytes(int bytesSize, long currentTimestamp) {
		totalBytesReceived += bytesSize;
		addDownloadData(bytesSize, currentTimestamp);
	}

	public void addUploadData(int totalBytes, long currentTime) {
		this.lastKey = currentTime;
		this.uploadMap.put(currentTime, (long) (this.totalBytesSent / 1024));
		// Log.i("Quality Server", totalBytes/1024/((currentTime - t0)/1000) +
		// " ko/s");
	}

	public void addDownloadData(int bytesRead, long currentTime) {
		this.lastKey = currentTime;
		this.downloadMap.put(currentTime,
				(long) (this.totalBytesReceived / 1024));
		// Log.i("Quality Client", bytesRead/1024/((currentTime - t0)/1000) +
		// " ko/s");
	}
	
	public long getStartTimestamp (){
		return this.startTimestamp;
	}

	public long getTotalDuration() {
		return ((this.endTimestamp - this.startTimestamp) / 1000);
	}

	public void unloadDownloadStat(OutputStreamWriter outputStreamWriter)
			throws IOException {
		if (isAlreadyUnloaded) {
			Log.i("NetworkQuality", "Already unloaded, exiting.");
			return;
		}
		outputStreamWriter.write("Schéma du tableau : \n");
		outputStreamWriter
				.write("Durée écoulée depuis le début - ko total reçus\n");
		for (Map.Entry<Long, Long> e : downloadMap.entrySet()) {
			outputStreamWriter
					.write(((e.getKey() - this.startTimestamp) / 1000) + ", "
							+ e.getValue() + "\n");
		}
		outputStreamWriter.write("Début : " + this.startTimestamp + "\n");
		outputStreamWriter.write("Fin : " + this.endTimestamp + "\n");
		outputStreamWriter.write("Durée totale : " + getTotalDuration()
				+ " secondes.\n");
		outputStreamWriter.write("Total ko Read : "
				+ (totalBytesReceived / 1024) + " ko.\n");
		this.isAlreadyUnloaded = true;
		Log.i("NetworkQuality", "Download stat unloaded." + "\n");
	}

	public void unloadUploadStat(OutputStreamWriter outputStreamWriter)
			throws IOException {
		if (isAlreadyUnloaded) {
			Log.i("NetworkQuality", "Already unloaded, exiting.");
			return;
		}
		outputStreamWriter.write("Schéma du tableau : \n");
		outputStreamWriter
				.write("Durée écoulée depuis le début - ko total envoyé\n");
		for (Map.Entry<Long, Long> e : uploadMap.entrySet()) {
			outputStreamWriter
					.write(((e.getKey() - this.startTimestamp) / 1000) + ", "
							+ e.getValue() + "\n");
		}
		outputStreamWriter.write("Début : " + this.startTimestamp + "\n");
		outputStreamWriter.write("Fin : " + this.endTimestamp + "\n");
		outputStreamWriter.write("Durée totale : " + getTotalDuration()
				+ " secondes.\n");
		outputStreamWriter.write("Total ko Sent : "
				+ (this.totalBytesSent / 1024) + " ko.\n");
		this.isAlreadyUnloaded = true;
		Log.i("NetworkQuality", "Upload stat unloaded.");
	}

	public String displayStats(boolean downloadStats) {
		if (downloadStats) {
			//Log.i("QoS", "download : " + downloadMap.get(this.lastKey) + " ko/s");
			if(downloadMap.get(this.lastKey)!=null)
				return downloadMap.get(this.lastKey) + " o/s";
			else 
				return "No data received ";
			
		}
		else {
			//Log.i("QoS","upload : " + uploadMap.get(this.lastKey) + " ko/s");
			return uploadMap.get(this.lastKey) + " o/s";
		}
	}
	
	public double getDownloadSpeed() {
		double ret = (double) ((totalBytesReceived) / 
						(double)((double)(double)((System.currentTimeMillis() - (double)startTimestamp)) / 
								(double)1000));
		//System.out.println("getDownloadSpeed() - download speed : " + ret);
		ret = Math.round( ret * 100.0 ) / 100.0;
		return ret;
	}
	
	public double getUploadSpeed() {
		double ret = (double) ((totalBytesSent) / 
					 (double)((double)(double)((System.currentTimeMillis() - (double)startTimestamp)) 
					/ (double)1000));
		//System.out.println("getUploadSpeed() - Upload speed : " + ret);
		ret = Math.round( ret * 100.0 ) / 100.0;
		return ret;
	}
	
	public double getTimeElapsed(){
		return (double)(double)((double)System.currentTimeMillis()- (double)startTimestamp)/1000;
	}
	
	public long getTotalBytesSended(){
		return (long)(this.totalBytesSent);
	}
	
	public long getTotalBytesReceived() {
		return (long)(this.totalBytesReceived);
	}
	
	/*
	 * private void initializeQualityFiles(statPath) { try { fileStat = new
	 * File(totoPath.replace(toto.getName(), "statClient.txt"));
	 * fileOutputStream = new FileOutputStream(fileStat); outputStreamWriter =
	 * new OutputStreamWriter(fileOutputStream); } catch (FileNotFoundException
	 * e) { e.printStackTrace(); } }
	 * 
	 * private void finalizeQualityFiles() { try { if (endTime == 0) endTime =
	 * System.currentTimeMillis();
	 * networkQuality.unloadDownloadStat(outputStreamWriter, startTime, endTime,
	 * totalBytesRead); outputStreamWriter.close(); fileOutputStream.close(); }
	 * catch (IOException e) { // TODO Auto-generated catch block
	 * e.printStackTrace(); } }
	 */

	

}
